#region License

/* Copyright (c) 2008, Dusty Candland
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * * Neither the name of Dusty Candland nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#endregion

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
using NUnit.Framework;

namespace NS3Library.Tests
{
    public abstract class IS3ServiceObjectFixture
    {
        private IS3Service _service;

        protected void SetService(IS3Service service)
        {
            _service = service;
        }

        [Test]
        public void ObjectPutGetPutGetDeleteTest()
        {
            EnsureBucket();
            GetObjectExpectNull();
            PutObject("myobject1");
            GetObject("myobject1");
            PutObject("myobject2");
            GetObjectListTestExpectOK(TestConstants.KeyName);
            GetObject("myobject2");
            DeleteObject();
        }

        protected void EnsureBucket()
        {
            if (_service.Get(TestConstants.BucketName) == null)
            {
                _service.Put(_service.CreateIS3Bucket(TestConstants.BucketName));
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
        }

        protected void GetObjectExpectNull()
        {
            IS3Object obj = _service.Get(TestConstants.BucketName, TestConstants.KeyName);
            if (obj != null)
                DeleteObject();
            Assert.That(obj, Is.Null);
        }

        protected void GetObjectListTestExpectOK(params string[] expectedObjects)
        {
            IS3Bucket awsBucket = _service.Get(TestConstants.BucketName);
            var list = new List<IS3ObjectKey>(awsBucket.S3ObjectKeys);
            Assert.That(list.Count, Is.GreaterThanOrEqualTo(expectedObjects.Length));
            foreach (string expectedObject in expectedObjects)
                Assert.That(
                    list.Find(delegate(IS3ObjectKey o) { return o.Key.Equals(expectedObject); }),
                    Is.Not.Null);
        }

        protected void DeleteObject()
        {
            _service.DeleteObject(TestConstants.BucketName, TestConstants.KeyName);
        }

        protected void PutObject(string content)
        {
            var meta = new NameValueCollection();
            meta.Add("x-amz-meta-test-meta-data", "data-tested");
            IS3Object is3Object = _service.CreateIS3Object(
                TestConstants.BucketName, TestConstants.KeyName, Encoding.UTF8.GetBytes(content), meta);
            IS3Object o = _service.Put(is3Object);
            Assert.That(o.Content, Is.EqualTo(Encoding.UTF8.GetBytes(content)));
        }

        protected void GetObject(string expectedContent)
        {
            IS3Object o = _service.Get(TestConstants.BucketName, TestConstants.KeyName);
            Assert.That(o, Is.Not.Null);
            Assert.That(o.ETag, Is.Not.Null);
            Assert.That(o.Size, Is.EqualTo(o.Content.Length));
            Assert.That(o.LastModified, Is.GreaterThan(DateTime.MinValue));
            Assert.That(o.Content, Is.EqualTo(Encoding.UTF8.GetBytes(expectedContent)));
            Assert.That(o.Metadata["x-amz-meta-test-meta-data"], Is.EqualTo("data-tested"));
        }
    }
}